/*
 * Created on 2005-5-29
 *
 */
package com.yl.cap.analyst.report.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.yl.cap.analyst.report.domain.Report;
import com.yl.cap.analyst.report.domain.ReportCode;
import com.yl.cap.analyst.report.domain.ReportLevel;
import com.yl.cap.analyst.user.domain.Group;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.type.Type;

import jaoso.framework.dao.hibernate.BaseDAOImpl;

/**
 * @author ZhangQi
 * 
 */
public class ReportDAOImpl extends BaseDAOImpl implements ReportDAO
{

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDao#getAllReport()
     */
    public List getAllReport()
    {
        // String hql = "from Report r where r.state=1";
        String hql = "from Report r order by r.type";
        List ret = this.getHibernateTemplate().find(hql);
        return ret;
    }

    public List getManagerAvailablyReport(String roleId)
    {
        String hql = "select distinct r from Report r left join r.groups rg where rg.id=? and r.state=1 order by r.type";
        return this.getHibernateTemplate().find(hql, roleId);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#getHaveLevel(java.lang.String,
     *      java.lang.String)
     */
    public ReportLevel getHaveLevel(String accountId, String reportId)
    {
        StringBuffer hql = new StringBuffer();
        hql
                .append("select rl from ReportLevel rl left join rl.groups as rg where rl.report.id=? and rg in (select elements(u.groups) from User u where u.account.id=?)");
        Type[] type =
        { Hibernate.STRING, Hibernate.STRING };
        Object[] value =
        { reportId, accountId };
        List levelList = this.getHibernateTemplate().find(hql.toString(),
                value, type);
        ReportLevel rl = null;
        ReportLevel tmpLevel = null;
        for (int i = 0; i < levelList.size(); i++)
        {
            tmpLevel = (ReportLevel) levelList.get(i);
            if (rl == null
                    || rl.getLevel().intValue() < tmpLevel.getLevel()
                            .intValue())
            {
                rl = tmpLevel;
            }
        }
        return rl;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#getReportCode(com.yl.cap.analyst.user.domain.Group,
     *      java.lang.String)
     */
    public String getReportCode(Set groups, String reportLevelId)
    {
        String hql = "select rc.code from ReportCode rc where rc.reportLevel.id=? and rc.name=?";
        Report tmpReport = ((ReportLevel) this.loadEntity(ReportLevel.class,
                reportLevelId)).getReport();

        List levelList = tmpReport.getReportLevel();
        ReportLevel rl = null;
        ReportLevel tmpLevel = null;
        List ret = null;
        for (int i = 0; i < levelList.size(); i++)
        {
            tmpLevel = (ReportLevel) levelList.get(i);
            if (rl == null
                    || rl.getLevel().intValue() < tmpLevel.getLevel()
                            .intValue())
            {
                rl = tmpLevel;
            }
        }

        if (reportLevelId.equals(rl.getId()))
        {
            hql = "select rc.code from ReportCode rc where rc.reportLevel.id=?";
            ret = this.getHibernateTemplate().find(hql, reportLevelId);
        }
        else
        {
            Group g = null;
            boolean isContain = false;
            outer:for (Iterator i = groups.iterator(); i.hasNext();)
            {
                g = (Group) i.next();
                for (int j = 0; j < g.getReportLevel().size(); j++)
                {
                    if (((ReportLevel) g.getReportLevel().get(j)).getId()
                            .equals(reportLevelId))
                    {
                        isContain = true;
                        break outer;
                    }
                }
            }
            if (!isContain)
            {
                return null;
            }
            Type[] type =
            { Hibernate.STRING, Hibernate.STRING };
            Object[] value =
            { reportLevelId, g.getPopedomField() };
            ret = this.getHibernateTemplate().find(hql, value, type);
        }

        if (ret == null || ret.size() == 0)
        {
            return null;
        }
        return (String) ret.get(0);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#getReportCode(java.lang.String,
     *      java.lang.String)
     */
    public boolean haveReportCode(String groupId, String code)
    {
        String hql = "from ReportCode rc where rc.code=? and rc.reportLevel.id in (select rl.id from ReportLevel rl left join rl.groups rg where rg.id=?)";
        Type[] type =
        { Hibernate.STRING, Hibernate.STRING };
        Object[] value =
        { code, groupId };
        List ret = this.getHibernateTemplate().find(hql, value, type);
        if (ret == null || ret.size() == 0)
        {
            return false;
        }
        return true;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#findReportByName(java.lang.String)
     */
    public List getReportByName(String name)
    {
        String hql = "from Report r where r.displayName like '" + name + "%'";
        return this.getHibernateTemplate().find(hql);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#findReportByDate(java.util.Date)
     */
    public List getReportByDate(Date date)
    {
        String hql = "from Report r where r.createDate=?";
        return this.getHibernateTemplate().find(hql, date);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#findAllReportType()
     */
    public List getAllReportType()
    {
        String hql = "select r.type from Report r where r.state='1' group by r.type";
        return this.getHibernateTemplate().find(hql);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#getAvailablyReport(java.lang.String)
     */
    public List getAvailablyReport(String accountId)
    {

        String hql = "select distinct rl.report from ReportLevel rl left join rl.groups rlg where rl.report.state='1' and rlg in (select elements(user.groups) from User user where user.account.id=?) order by rl.report.type";
        List reports = this.getHibernateTemplate().find(hql, accountId);
        return reports;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#getLevelByName(java.lang.String,
     *      java.lang.String)
     */
    public ReportLevel getLevelByName(String reportId, String levelName)
    {
        String hql = "from ReportLevel rl where rl.report.id=? and rl.name=?";
        Type[] type =
        { Hibernate.STRING, Hibernate.STRING };
        Object[] value =
        { reportId, levelName };
        List ret = this.getHibernateTemplate().find(hql, value, type);
        if (ret == null || ret.size() == 0)
        {
            return null;
        }
        return (ReportLevel) ret.get(0);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.yl.cap.analyst.report.dao.ReportDAO#getUserByReport(java.lang.String)
     */
    public List getUserByReport(String reportId)
    {
        String hql = "select distinct u from User u,u.group ug left join ug.reportLevel ugr where ugr.report.id=?";
        return this.getHibernateTemplate().find(hql, reportId);
    }

    public List getCodeList(String accountId)
    {
        // Set groupSet = ((Account) this.getHibernateTemplate().load(
        // Account.class, accountId)).getUser().getGroups();
        List groupSet = this
                .getHibernateTemplate()
                .find(
                        "select elements(user.groups) from User as user where user.account.id=?",
                        accountId);

        List tmpCodes = null;
        List codeList = new ArrayList();
        String hql = "from ReportCode rc where rc.reportLevel.id in (select rl.id from ReportLevel rl left join rl.groups rg where rg.id=?)";
        for (Iterator i = groupSet.iterator(); i.hasNext();)
        {
            tmpCodes = this.getHibernateTemplate().find(hql,
                    ((Group) i.next()).getId());
            for (int j = 0; j < tmpCodes.size(); j++)
            {
                codeList.add(((ReportCode) tmpCodes.get(j)).getCode());
            }
        }
        return codeList;
    }
}
